#include "Inf_DS1302.h"

static void Inf_DS1302_WriteRegister(uint8_t reg, uint8_t data)
{
    // 拉高CE开始通信
    HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_SET);
    HAL_Delay(1);
    // 发送控制字节
    for (uint8_t i = 0; i < 8; i++)
    {
        if(reg & 0x01)
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_RESET);
        }
        reg >>= 1;
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_RESET);
        HAL_Delay(1);
    }
    // 发送数据
    for (uint8_t i = 0; i < 8; i++)
    {
        if(data & 0x01)
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_RESET);
        }
        data >>= 1;
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_RESET);
        HAL_Delay(1);
    }
    // 拉低CE结束通信
    HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_RESET);
    HAL_Delay(1);
}

static uint8_t Inf_DS1302_ReadRegister(uint8_t reg)
{
    uint8_t data = 0;
    // 拉高CE开始通信
    HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_SET);
    HAL_Delay(1);
    // 发送控制字节
    for (uint8_t i = 0; i < 8; i++)
    {
        if(reg & 0x01)
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_SET);
        }
        else
        {
            HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_RESET);
        }
        reg >>= 1;
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_RESET);
        HAL_Delay(1);
    }
    // 释放IO总线
    HAL_GPIO_WritePin(DS1302_IO_GPIO_Port, DS1302_IO_Pin, GPIO_PIN_SET);
    // 接收数据
    for (uint8_t i = 0; i < 8; i++)
    {
        data >>= 1;
        if(HAL_GPIO_ReadPin(DS1302_IO_GPIO_Port, DS1302_IO_Pin))
        {
            data |= 0x80;
        }
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_SET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DS1302_CLK_GPIO_Port, DS1302_CLK_Pin, GPIO_PIN_RESET);
        HAL_Delay(1);
    }
    // 拉低CE结束通信
    HAL_GPIO_WritePin(DS1302_RST_GPIO_Port, DS1302_RST_Pin, GPIO_PIN_RESET);
    HAL_Delay(1);
    return data;
}

void Inf_DS1302_ReadTime(datetime_t *time)
{
    uint8_t byte = Inf_DS1302_ReadRegister(DS1302_Seconds_Reg + 1);
    time->second = (byte >> 4) * 10 + (byte & 0x0F);
    byte = Inf_DS1302_ReadRegister(DS1302_Minutes_Reg + 1);
    time->minute = (byte >> 4) * 10 + (byte & 0x0F);
    byte = Inf_DS1302_ReadRegister(DS1302_Hour_Reg + 1);
    time->hour = (byte >> 4) * 10 + (byte & 0x0F);
    byte = Inf_DS1302_ReadRegister(DS1302_Date_Reg + 1);
    time->date = (byte >> 4) * 10 + (byte & 0x0F);
    byte = Inf_DS1302_ReadRegister(DS1302_Month_Reg + 1);
    time->month = (byte >> 4) * 10 + (byte & 0x0F);
    time->day = (Week_t)Inf_DS1302_ReadRegister(DS1302_Day_Reg + 1);
    byte = Inf_DS1302_ReadRegister(DS1302_Year_Reg + 1);
    time->year = (byte >> 4) * 10 + (byte & 0x0F);
}

void Inf_DS1302_WriteTime(datetime_t *time)
{
    uint8_t byte = ((time->second / 10) << 4) | (time->second % 10);
    Inf_DS1302_WriteRegister(DS1302_Seconds_Reg, byte);
    byte = ((time->minute / 10) << 4) | (time->minute % 10);
    Inf_DS1302_WriteRegister(DS1302_Minutes_Reg, byte);
    byte = ((time->hour / 10) << 4) | (time->hour % 10);
    Inf_DS1302_WriteRegister(DS1302_Hour_Reg, byte);
    byte = ((time->date / 10) << 4) | (time->date % 10);
    Inf_DS1302_WriteRegister(DS1302_Date_Reg, byte);
    byte = ((time->month / 10) << 4) | (time->month % 10);
    Inf_DS1302_WriteRegister(DS1302_Month_Reg, byte);
    Inf_DS1302_WriteRegister(DS1302_Day_Reg, time->day);
    byte = ((time->year / 10) << 4) | (time->year % 10);
    Inf_DS1302_WriteRegister(DS1302_Year_Reg, byte);
}
